





let defaultColor = ['#12e78c','#01C2F9','#00FFE3',
    '#3473FF','#afa3f5','#fe8104','#01C2F9',
    '#f0cc26','#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4']
function init_char (emid, option) {
    let dm = document.getElementById(emid)
    let echat = echarts.init(dm)
    echat.setOption(option);
    window.addEventListener("resize", () => {
        echat.resize();
    });
    return echat;
}
function  dateFtt(fmt, date) {
    if (typeof date == "string") {
        date = new Date(date);
    }
    let o = {
        'M+': date.getMonth() + 1,
        'd+': date.getDate(),
        'h+': date.getHours(),
        'm+': date.getMinutes(),
        's+': date.getSeconds(),
        'q+': Math.floor((date.getMonth() + 3) / 3),
        S: date.getMilliseconds()
    }
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, String(date.getFullYear()).substr(4 - RegExp.$1.length))
    for (let k in o)
        if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(String(o[k]).length))
    return fmt
}

/**
 * 圆环
 * @param emid
 * @param chartData
 * @constructor
 */

function RING  (emid, chartData) {
    let arrName = [];
    let arrValue = [];
    let sum = 0;
    let pieSeries = [],
        lineYAxis = [];

// 数据处理
    chartData.forEach((v, i) => {
        arrName.push(v.name);
        arrValue.push(v.value);
        sum = sum + v.value;
    })

// 图表option整理
    chartData.forEach((v, i) => {
        pieSeries.push({
            type: 'pie',
            clockwise: false,
            emphasis: {
                scale: false,
            },
            radius: [75 - i * 15 + '%', 67 - i * 15 + '%'],
            center: ["35%", "50%"],
            label: {
                show: false
            },
            data: [{
                value: v.value,
                name: v.name
            }, {
                value: sum - v.value,
                name: '',
                itemStyle: {
                    color: '#efefef',
                }
            }]
        });
        v.percent = (v.value / sum * 100).toFixed(1) + "%";
        lineYAxis.push({
            value: i,
            textStyle: {
                rich: {
                    circle: {
                        color: defaultColor[i],
                        padding: [0, 5]
                    }
                }
            }
        });
    })
    let oper = {
        color: defaultColor,
        yAxis: [{
            type: 'category',
            inverse: true,
            axisLine: {
                show: false
            },
            axisTick: {
                show: false
            },
            axisLabel: {
                formatter: function (params) {
                    let item = chartData[params];
                    return '{line|}{circle|●}{name|' + item.name + '}{bd||}{percent|' + item.percent + '}{bd||}{percent|' + item.value + '}'
                },
                interval: 0,
                inside: true,
                rich: {
                    line: {
                        width: 250,
                        height: 30,
                        lineHeight: 30
                    },
                    name: {
                        color: '#666',
                        fontSize: '14px',
                    },
                    bd: {
                        color: '#ccc',
                        padding: [0, 5],
                        fontSize: '14px',
                    },
                    percent: {
                        color: '#666',
                        fontSize: '14px',
                    },
                    value: {
                        color: '#666',
                        fontSize: '14px',

                    },
                },
                show: true,
            },
            data: lineYAxis
        }],
        xAxis: [{
            show: false
        }],

        series: pieSeries
    };
    init_char(emid, oper)
}

/**
 * 环形图
 * @param emid
 * @param title
 * @param value
 * @param unit
 */
function GAUGE  (emid, title, value, unit = '', angle) {
    let option = {
        title: [
            {
                text: "{a|" + value + "}{c|" + unit + " }",
                x: "center",
                y: "center",
                textStyle: {
                    rich: {
                        a: {fontSize: 40, color: "#29EEF3",},
                        c: {fontSize: 16, color: "#29EEF3",},
                    },
                },
            },
            {
                text: title,
                x: "center",
                top: "62%",
                textStyle: {
                    color: "#04c9ff",
                    fontSize: 26,
                    fontWeight: "600",
                },
            },
        ],
        series: [
            {
                type: 'gauge',
                radius: '88%',
                center: ['50%', '50%'],
                splitNumber: 10, //刻度数量
                startAngle: angle ? angle[0] : 360,
                endAngle: angle ? angle[1] : 30,
                axisLine: {
                    show: true,
                    lineStyle: {
                        width: 15,
                        color: [[0.9, new echarts.graphic.LinearGradient(
                            0, 0, 1, 0, [{
                                offset: 0,
                                color: '#5c53de'
                            },
                                {
                                    offset: 1,
                                    color: '#18c8ff'
                                }])],
                            [
                                1, '#413e54'
                            ]
                        ]
                    }
                },
                //分隔线样式。
                splitLine: {show: false,},
                axisLabel: {
                    show: false
                },
                axisTick: {
                    show: false
                },
                pointer: {
                    show: false
                },
                detail: {
                    show: false,
                },
                data: [{value: value,}]
            }
        ]
    };
    if (emid == undefined) {
        return option
    } else {
        init_char(emid, option);
    }
}
/**
 * 实心饼图
 * @param emid:
 * @param title:
 * @param data::
 * @param unit
 */
function PIE  (emid, title, data, unit, oper = {})  {
    let option = {
        color: oper.color ? oper.color : [
            "#00d488",
            "#3feed4",
            "#3bafff",
            "#afa3f5",
            "#f1bb4c", "rgba(250,250,250,0.5)"
        ],
        tooltip: {
            trigger: 'item',
            formatter: function (params) {
                if (params.name !== '') {
                    return `${params.name}：${params.value}${unit ? unit : ''} ` + `\n\n占比：${params.percent === undefined ? 0 : params.percent}%`
                }
                return ''
            }
        },
        legend: {top: '0%', textStyle: {color: '#229aff'}},
        series: [{
            type: 'pie',
            radius: oper.radius ? oper.radius : '50%',
            center: ['50%', '50%'],
            data: data,
            label: {
                formatter: function (params) {
                    if (params.name !== '') {
                        return `${params.name}：${params.value}${unit ? unit : ''} ` + `\n\n占比：${params.percent === undefined ? 0 : params.percent}%`
                    }
                    return ''
                },
                color: '#229aff',
                fontSize: 12
            },
        }]
    }
    init_char(emid, option);
}

/**
 * 横向列表图
 * @param emid
 * @param title
 * @param data
 * @param unit
 * @param oper
 * @constructor
 */
function LISTV  (emid, title, datas, unit = '', oper = {})  {
    datas.sort((a, b) => b.value - a.value);
    let colors = oper.color ? oper.color : defaultColor;
    let option = {

        color: colors,
        tooltip: {
            trigger: "axis",
            axisPointer: {
                type: "shadow",
            },
        },
        xAxis: {
            show: oper.show ? oper.show : false,
            type: "value",
        },
        grid: {
            top: '10',
            bottom: "20",
            left: '65',
            right: '120'
        },
        yAxis: [
            {
                type: "category",
                inverse: true,
                axisLine: {
                    show: false,
                },
                axisTick: {
                    show: false,
                },
                axisPointer: {
                    label: {
                        show: true,
                        margin: 30,
                    },
                },
                axisLabel: {
                    show: true,
                    fontSize: 14,
                    color: "#4962FC",
                },
                data: datas.map((item) => item.name),
            },
            {
                type: "category",
                inverse: true,
                axisTick: "none",
                axisLine: "none",
                show: true,
                data: datas.map((item) => item.value),
                axisLabel: {
                    show: true,
                    fontSize: 14,
                    color: "#4962FC",
                    formatter: "{value} " + unit,
                },
            },
        ],
        series: [
            {
                name: "value",
                type: "bar",
                barMaxWidth: 20,
                zlevel: 1,
                data: datas.map((item, i) => {
                    return {
                        value: item.value,
                        itemStyle: {color: i > colors.length ? colors[colors.length - 1] : colors[i % 10]},
                    };
                }),
            },
        ],
    };
    if (Object.keys(oper).length > 0) option = Object.assign(option, oper);
    init_char(emid, option);
}


/**
 * 桑吉图
 * @param emid:
 * @param title:
 * @param series:
 * @param unit
 * @param oper
 */
// 桑基图数据格式要求如下↓，nodes中的节点需要和links互相对应，node表示图
// 上的节点，link对应节点间的关系，如需自定义节点颜色需要在数据中单独设置
// 否则只能设置某层节点的颜色，由于link连线中只有source和target两个节点关系
// 所以鼠标滑过高亮从第一层到最后一层的节点需求无法实现，在level中可以单独
// 设置某个层级的样式
function SANKEY  (emid, title, series, unit, oper = {}) {
    let colors = oper.color ? oper.color : defaultColor;
    var nodes = series.nodes, links = series.links;
    for (let d = 0; d < nodes.length; d++) {
        nodes[d].label = {
            textStyle: {
                position: "inside",
                align: "center",
                padding: [0, 0, 0, -130],
                fontSize: 18,
                fontWeight: 800,
                color: "#535252",
            },
        }

        nodes[d].itemStyle = {

            color: colors[d],
        };

    }
    var option = {
        tooltip: {
            trigger: "item",
            triggerOn: "mousemove",
        },
        series: {
            type: "sankey",
            layout: "none",
            orient: "vertical",//纵向排列，默认值为横向
            top: 50,
            left: 50,
            right: 50,
            nodeGap: 14,
            layoutIterations: 0, // 自动优化列表，尽量减少线的交叉，为0就是按照数据排列
            data: nodes, // 节点
            links: links, // 节点之间的连线
            draggable: false,
            focusNodeAdjacency: "allEdges", // 鼠标划上时高亮的节点和连线，allEdges表示鼠标划到节点上点亮节点上的连线及连线对应的节点
            levels: [
                {
                    depth: 0,
                    itemStyle: {
                        color: "#5AAEF4",
                    },
                    lineStyle: {
                        color: "source",
                        opacity: 0.3,
                    },
                },
                {
                    depth: 1,

                    lineStyle: {
                        color: "source",
                        opacity: 0.3,
                    },
                },
                {
                    depth: 2,
                    lineStyle: {
                        color: "source",
                        opacity: 0.3,
                    },
                },
                {
                    depth: 3,
                    label: {
                        fontSize: 10,
                    },
                },
            ],
            label: {
                fontSize: 10,
                color: "#666",
            },
            itemStyle: {
                borderWidth: 0,
            },
        },
    };
    if (title) option.title = {text: title};
    if (Object.keys(oper).length > 0) option = Object.assign(option, oper);
    return init_char(emid, option)

}


function init_baschat  (series, unit, oper = {}) {
    let color = oper.color || defaultColor;
    for (let i in series) {
        let serie = series[i], sdata = serie.data
        if (sdata.length > 0 && typeof sdata[0] == 'object') {
            let _array = [];
            for (let item of sdata) {
                _array.push([item.time, item.value, item.color])
            }
            serie.data = _array;
        }
        if (serie.type == 'bar') {
            //渐变色支持
            let scolor = serie.gradient ?
                new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0, color: "#00FFE3"}, { offset: 1,color: color[parseInt(i) + (oper.colorindex || 0)]}]) : defaultColor[parseInt(i) + (oper.colorindex || 0)];
            serie = Object.assign(serie, {
                barMaxWidth: 15,
                stack: serie.stack ? serie.stack : '',
                itemStyle: {
                    color: (val) => { return undefined != val.data[2]? "#FF1493":scolor; },
                }
            })
        } else {
            serie = Object.assign(serie, {
                smooth: true, //平滑曲线显示
                showAllSymbol: true, //显示所有图形。
                symbol: "circle", //标记的图形为实心圆
                symbolSize: 3, //标记的大小
                areaStyle: {opacity: 0.15},
                showSymbol: oper.showSymbol !== undefined ? oper.showSymbol : true,
            })
        }
    }
    let option = {
        color: color,
        toolbox: oper.showToolbox ? {
            top: "0",
            right: 50,
            iconStyle: {
                borderColor: "#565555"
            },
            feature: {
                dataZoom: {
                    yAxisIndex: "none"
                },
                saveAsImage: {
                    backgroundColor: "#2f2a48",
                    type: "jpeg"
                }
            }
        } : {},
        tooltip: {
            trigger: 'axis',
            formatter: (params) => {
                let result = '';
                params.forEach(function (item, index) {
                    // item 是每一个系列的数据
                    const seriesName = item.seriesName, value = item.value, marker = item.marker;
                    let _unit = "";
                    let _u = unit.length == 1 ? unit[0] : unit && unit[item.seriesIndex];
                    if (_u) _unit = typeof _u == 'object' ? _u[value[1]] || '' : _u;
                    if (result === '') result = `${value[0]}<br/>`
                    result += `${marker}${seriesName}: ${typeof _u == 'object' ? '' : value[1]} ${_unit}<br/>`;
                });
                return result;
            }
        },

        grid: {
            bottom: "10%",
            left: '45',
            right: '35'
        },
        legend: {
            top: "5%",
            textStyle: {color: color}
        },
        xAxis: [{
            type: 'category',
            axisLine: {lineStyle: {color: '#058cff'}},
            axisLabel: {interval: 5}

        }],
        yAxis: {
            type: 'value',
            splitLine: {lineStyle: {opacity: 0.3}},
            axisLabel: {color: "#058cff"},
        },
        series: series
    };
    return option;
}

/**
 * 柱形,折线图
 * @param emid:
 * @param title:
 * @param data:
 * @param unit
 * @param echarttype:图表类型
 */
function DEFCHART (emid, title, series, unit, oper = {},) {
    let option = init_baschat(series, unit, oper);
    if (title) option.title = {text: title};
    if (Object.keys(oper).length > 0) option = Object.assign(option, oper);
    return init_char(emid, option);
}

/**
 * 时间轴柱形,折线图
 * @param emid:
 * @param title:
 * @param data:
 * @param unit
 * @param echarttype:图表类型
 */
function TIMECHART  (emid, title, series, unit, oper = {}) {
    let select = {}
    series.map(item => {
        select[item.name] = oper.selectedOne ? item.selected : true
    })
    let option = init_baschat(series, unit, oper);
    option.legend.selected = select;
    option.dataZoom = [
        {
            type: 'inside',
            start: 0,
            end: 100
        }
    ]
    option.xAxis = [{
        type: 'time',
        minInterval: oper.interval ? oper.interval : 3600 * 1000 * 0.5,
        axisLine: {lineStyle: {color:  series[0].color|| '#058cff'}},
        splitLine: {show: false},
        axisLabel: {
            interval: 5,
            formatter: function (value) {
                let date = new Date(value)
                let dateTime1 =dateFtt(oper.format ? oper.format : 'yy-MM-dd hh:mm:ss', date)
                return dateTime1
            }
        },
        triggerEvent: true,
    }]
    if (title) option.title = {text: title};
    if (Object.keys(oper).length > 0) option = Object.assign(option, oper);
    return init_char(emid, option);
}
//南丁格尔玫瑰图
function intCharare  (emid, data) {
    var options = {
        tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        legend: {
            right: 10,
            top: 0,
            orient: 'vertical',
            type: 'scroll',
            height: 160,
            textStyle: {
                color: '#09edfc'
            },
            show: true,
        },
        toolbox: {
            show: false,
            feature: {
                mark: {show: true},
                dataView: {show: true, readOnly: false},
                magicType: {
                    show: true,
                    type: ['pie', 'funnel']
                },
                restore: {show: true},
                saveAsImage: {show: true}
            }
        },
        series: [
            {
                name: '项目分布',
                type: 'pie',
                radius: [20, 70],
                center: ['40%', '40%'],
                roseType: 'radius',
                label: {
                    show: true
                },
                emphasis: {
                    label: {
                        show: true
                    }
                },
                data: data.seriesdata,
                color: [
                    "#00d488",
                    "#3feed4",
                    "#3bafff",
                    "#afa3f5",
                    "#f1bb4c",
                    "rgba(250,250,250,0.5)",
                ]
            },
        ]
    };
    init_char(emid, options)
}
// 自定义图表
function CUSTOME  (emid, title, series, unit, oper) {
    var r = [];
    oper.colmn.forEach((e, a) => {
        var n = optionSeries(e, series, a);
        r.push(n)
    });

    function optionSeries(t, e, i) {
        var a;
        return a = {
            name: t.label,
            type: "custom",
            encode: {
                x: [1, 2],
                y: 0
            },
            data: e[t.value],
            renderItem: function (params, api) {
                var i = api.value(0)
                    , a = api.coord([api.value(1), i])
                    , n = api.coord([api.value(2), i])
                    , r = .6 * api.size([0, 1])[1]
                    , s = echarts.graphic.clipRectByRect({
                    x: a[0],
                    y: a[1] - r / 2,
                    width: n[0] - a[0],
                    height: r
                }, {
                    x: params.coordSys.x,
                    y: params.coordSys.y,
                    width: params.coordSys.width,
                    height: params.coordSys.height
                });
                return s && {
                    type: "rect",
                    shape: s,
                    style: api.style()
                }
            },
            stack: "总量",
            itemStyle: {
                opacity: .8,
                color: t.color
            }
        }
    }

    var option = {
        legend: {
            height: 80,
            inactiveColor: "#777",
            textStyle: {
                fontSize: 16,
                // color: "#ccc"
            }
        },
        toolbox: {
            top: "0",
            right: 50,
            iconStyle: {
                borderColor: "#565555"
            },
            feature: {
                dataZoom: {
                    yAxisIndex: "none"
                },
                saveAsImage: {
                    backgroundColor: "#2f2a48",
                    type: "jpeg"
                }
            }
        },
        grid: {
            left: 140,
            right: 20,
            bottom: 30
        },
        tooltip: {
            textStyle: {
                align: "left"
            },
            position: function (point, params, dom, rect, size) {
                var r = point[0] //鼠标位置
                    , s = size.contentSize[0];//dom 的尺寸
                return [r < s ? 5 : r - s, "20%"]
            },
            formatter: function (t) {
                if (t.value) {
                    var e = t.value[1]
                        , a = t.value[2]
                        , n = ((t.value[2] - t.value[1]) / 60000).toFixed(2)
                        , r = 0;
                    n > 60 && (r = parseInt(n / 60),
                        n = parseInt(n % 60));
                    var o = r ? r + "小时" + n + "分钟" : n + "分钟"
                        , l = "";
                    l = t.seriesName + "时长";
                    return t.marker + t.name + "<br/>开始时间 : " + syscomm.dateFtt('MM-dd hh:mm:ss', new Date(e)) + "<br/>结束时间 : " + syscomm.dateFtt('MM-dd hh:mm:ss', new Date(a)) + "<br/>" + l + " : " + o
                }
            }
        },
        xAxis: {
            type: "time",
            scale: !0,
            axisLine: {
                lineStyle: {
                    color: "#000"
                }
            },
            axisLabel: {
                formatter: function (t) {
                    return syscomm.dateFtt('MM-dd hh:mm:ss', new Date(t))
                }
            },
        },
        yAxis: {
            data: oper.names,
            inverse: !0,
            axisLine: {
                lineStyle: {
                    color: "#6b6a6a"
                }
            },
            axisLabel: {
                fontSize: 16,
                color: "#058cff",
            }
        },
        series: r
    };
    return init_char(emid, option)
}
// 频谱图
function  SURFACE  (emid, title, series, unit, oper) {
    let max = 0, min = 0;
    series.map((e, index) => {
        max = e[2] > max ? e[2] : max
        min = e[2] < min ? e[2] : min
    })
    var options = {
        tooltip: {
            formatter: function (params) {
                let time = new Date(params.value[1]).toLocaleString();
                return `X：${params.data[0]} ` + `<br/> Y：${time} ` + `<br/> Z：${params.data[2]} `
            }
        },
        grid3D: {
            boxWidth: 200,
            splitLine: {
                interval: 0
            },
            viewControl: {
                // 使用正交投影。
                projection: 'orthographic',
                distance: 300,
            }
        },
        xAxis3D: {
            type: 'category',
        },
        yAxis3D: {
            type: 'time'
        },
        zAxis3D: {},
        visualMap: {
            calculable: true,
            min: min,
            max: max,
            // 维度的名字默认就是表头的属性名
            dimension: 'value',
            inRange: {
                color: ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
            }
        },
        dataset: {
            dimensions: [
                'point',
                {name: 'time', type: 'ordinal'},
                'value',
            ],
            source: series,
        },
        series: [
            {
                type: 'bar3D',
                shading: 'lambert',
                encode: {
                    x: 'point',
                    y: 'time',
                    z: 'value',
                    tooltip: [0, 1, 2]
                }
            }
        ]
    };
    return init_char(emid, options)
}

function BOXPLOT   (emid, title, series, unit, oper) {
    let options = {
        title: [
            {
                text: title,
                left: 'center'
            }
        ],
        tooltip: {
            trigger: 'item',
            axisPointer: {
                type: 'shadow'
            }
        },
        grid: {
            left: '10%',
            right: '10%',
            bottom: '15%'
        },
        dataset: [
            {
                // 这个 dataset 的 index 为 `0`。
                source: series,
            },
            {
                // 这个 dataset 的 index 为 `1`。
                transform: {
                    type: 'boxplot'
                }
                // 这个 "boxplot" transform 生成了两个数据：
                // result[0]: boxplot series 所需的数据。
                // result[1]: 离群点数据。
                // 当其他 series 或者 dataset 引用这个 dataset 时，他们默认只能得到
                // result[0] 。
                // 如果想要他们得到 result[1] ，需要额外声明如下这样一个 dataset ：
            },
            {
                // 这个 dataset 的 index 为 `2`。
                // 这个额外的 dataset 指定了数据来源于 index 为 `1` 的 dataset。
                fromDatasetIndex: 1,
                // 并且指定了获取 transform result[1] 。
                fromTransformResult: 1
            }
        ],
        xAxis: {
            type: 'category',
            name: oper.name[1],
            boundaryGap: true,
            nameGap: 30,
            splitArea: {
                show: false
            },
            splitLine: {
                show: false
            }
        },
        yAxis: {
            type: 'value',
            name: oper.name[1],
            splitArea: {
                show: true
            }
        },
        series: [
            {
                name: 'boxplot',
                type: 'boxplot',
                datasetIndex: 1
            },
            {
                name: 'outlier',
                type: 'scatter',
                datasetIndex: 2
            }
        ]
    };
    return init_char(emid, options)
}

function  HEATMAP   (emid, title, series, unit, oper) {
    let options = {
        tooltip: {
            position: 'top'
        },
        grid: {
            height: '50%',
            top: '10%'
        },
        xAxis: oper.xAxis ? oper.xAxis : {
            type: 'category',
            splitArea: {
                show: true
            }
        },
        yAxis: oper.yAxis ? oper.yAxis : {
            type: 'category',
            splitArea: {
                show: true
            }
        },
        visualMap: {
            min: 0,
            max: 10,
            calculable: true,
            orient: 'horizontal',
            left: 'center',
            bottom: '15%'
        },
        series: [
            {
                name: 'Punch Card',
                type: 'heatmap',
                data: series,
                label: {
                    show: true
                },
                emphasis: {
                    itemStyle: {
                        shadowBlur: 10,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }
        ]
    };
    return init_char(emid, options)
}


